﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#ifdef _WINDOWS
#include "GcmpDevService.h"

#include <windows.h>
#include <TlHelp32.h>
#include <xstring>

/// \brief Windows平台mutex实现。
///
/// 在Windows上，std::mutex效率低，使用Mutex和MutexLockGuard替代
class Mutex
{
public:
    Mutex() : m_handle(NULL)
    {
        m_handle = CreateMutex(NULL, FALSE, NULL);
    }
    ~Mutex()
    {
        if (m_handle)
        {
            CloseHandle(m_handle);
            m_handle = NULL;
        }
    }
    Mutex(const Mutex& mutex) { *this = mutex; }
    Mutex& operator=(const Mutex& other)
    {
        if (this != &other)
        {
            m_handle = other.m_handle;
        }
        return *this;
    }
    void Lock()
    {
        WaitForSingleObject(m_handle, INFINITE);
    }

    void Unlock()
    {
        ReleaseMutex(m_handle);
    }
private:
    HANDLE m_handle;
};

class MutexLockGuard
{
public:
    MutexLockGuard(Mutex & mutex) : m_mutex(mutex) { m_mutex.Lock(); }
    ~MutexLockGuard() { m_mutex.Unlock(); }
private:
    Mutex & m_mutex;
};

/// \brief Windows平台临界区封装。
///
/// 临界区的效率比Mutex更高
class CriticalSectionLock
{
public:
    CriticalSectionLock()
    {
        InitializeCriticalSection(&m_criticalSection);
    }
    ~CriticalSectionLock()
    {
        DeleteCriticalSection(&m_criticalSection);
    }

    CriticalSectionLock(const CriticalSectionLock& criticalSectionLock) = delete;

    CriticalSectionLock& operator =(const CriticalSectionLock& other) = delete;

    void Lock()
    {
        EnterCriticalSection(&m_criticalSection);
    }
    void UnLock()
    {
        LeaveCriticalSection(&m_criticalSection);
    }
private:
    CRITICAL_SECTION                m_criticalSection;            //临界区变量  
};

class CriticalSectionLockGuard
{
public:
    CriticalSectionLockGuard(CriticalSectionLock& criticalSectionLock):m_criticalSectionLock(criticalSectionLock)
    {
        m_criticalSectionLock.Lock();
    }
    ~CriticalSectionLockGuard()
    {
        m_criticalSectionLock.UnLock();
    }

private:
    CriticalSectionLock& m_criticalSectionLock;
};

#define HighPerformanceMutex CriticalSectionLock
#define HighPerformanceMutexLockGuard CriticalSectionLockGuard

GCMP_DEV_SERVICE_EXPORT LONG WINAPI MiniDumpFilter(struct _EXCEPTION_POINTERS* exception);

GCMP_DEV_SERVICE_EXPORT bool HasProcess(const std::wstring& Process);

GCMP_DEV_SERVICE_EXPORT void RegistCellOCXControl();

GCMP_DEV_SERVICE_EXPORT std::string GetLastErrorAsString();

GCMP_DEV_SERVICE_EXPORT std::set<std::wstring> GetSystemDefaultEudcFontPath();

GCMP_DEV_SERVICE_EXPORT std::wstring GetSystemTime();

GCMP_DEV_SERVICE_EXPORT void EmptyMemoryWorkingSet();

GCMP_DEV_SERVICE_EXPORT uint32_t GetNumberOfProcessors();

GCMP_DEV_SERVICE_EXPORT size_t GetAvailableMemory();

GCMP_DEV_SERVICE_EXPORT std::wstring GetCpuProcessorName();

GCMP_DEV_SERVICE_EXPORT BOOL Is64bitSystem();

GCMP_DEV_SERVICE_EXPORT std::string GetModuleFilePath(const std::string& moduleName);
#else
#define HWND unsigned long long
void OutputDebugString(const wchar_t *lpOutputString);
unsigned int GetCurrentThreadId();
unsigned long GetTickCount();
short GetKeyState(int nVirtKey);
bool IsBadReadPtr(void *lp,size_t ucb);
bool IsBadWritePtr(void* lp,size_t ucb);
void DebugBreak();

#define VK_LBUTTON          0x01
#define VK_RBUTTON          0x02
#define VK_CANCEL           0x03
#define VK_MBUTTON          0x04
#define VK_SHIFT            0x10
#define VK_CONTROL          0x11
#define VK_MENU             0x12
#define VK_RETURN           0x0D
#define VK_ESCAPE           0x1B
#define VK_DELETE           0x2E
#define VK_SPACE            0x20
#define VK_TAB              0x09

typedef unsigned long       DWORD;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;
#define RGB(r,g,b)          ((DWORD)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))

int GetLastError();

typedef void* HINSTANCE;
HINSTANCE LoadLibrary(const wchar_t* lpLibFileName);
bool FreeLibrary(HINSTANCE hLibModule);
void* GetProcAddress(HINSTANCE hModule, const wchar_t* lpProcName);
uint32_t GetNumberOfProcessors();
size_t GetAvailableMemory();

#define HighPerformanceMutex std::mutex
#define HighPerformanceMutexLockGuard std::lock_guard<std::mutex>

#endif
